const moment = require('moment')
const axios = require('axios')
var rewire = require("rewire")
const fs = require('fs')
const { v4: uuidv4 } = require('uuid')
const {getLogger} = rewire('../common/logger.cjs')
const logger = getLogger('utils')


function clearRequireCache() {
    Object.keys(require.cache).forEach(function(key) {
        delete require.cache[key];
    })
}

//Object.keys(require.cache).filter(key => key.endsWith('cjs'))


function urlEncode(text) {
    return encodeURIComponent(text)
}

function sleep(ms) {
    return new Promise((resolve) => {setTimeout(resolve, ms)})
}


function strToTimestamp(timestr, fm) {
    return moment(timestr, fm).valueOf()
}

function nowDateStr() {
    return moment().format('YYYYMMDD')
}

function currentMs() {
    return moment().valueOf()
}

function currentSec() {
  return Math.floor(currentMs() / 1000)
}

function timestampToStr(time, fm) {
    return moment(time).format(fm)
}

function shortCNToTimestamp(cnstr) {
    const now = (new Date()).getTime()
    if (cnstr === '刚刚') {
        return now - 1000
    }
    const num = extractNum(cnstr)
    if (num <= 0) {
        logger.error("时间字符串的格式有误")
        return 0
    }
    if (cnstr.includes('秒')) {
        return now - num * 1000
    }
    if (cnstr.includes('分')) {
        return now - num * 1000 * 60
    }
    if (cnstr.includes('时')) {
        return now - num * 1000 * 60 * 60
    }
    if (cnstr.includes('天')) {
        return now - num * 1000 * 60 * 60 * 24
    }
    if (cnstr.includes('周')) {
        return now - num * 1000 * 60 * 60 * 24 * 7
    }
    logger.error("时间字符串的格式不支持: " + cnstr)
    return 0
}

// 从字符串中提取数字
function extractNum(cnstr) {
    const arr = cnstr.match(/\d+(.\d+)?/g)
    if (arr && arr.length > 0) {
        return parseInt(arr[0])
    }
    return 0
}


// 裁剪字符串，且不会发生断句问题
function strSentenceCut(text, len) {
    function loop(sentences, sent0Len) {
        if (sentences.length == 1) {
            return [sentences[0], '']
        }
        if (sent0Len >= len) {
            return [sentences[0], sentences.slice(1).join("")]
        }
        const sentLen0_1 = (sent0Len + stringLength(sentences[1]))
        if (sentLen0_1 > len) {
            return [sentences[0], sentences.slice(1).join("")]
        }
        return loop([sentences[0] + sentences[1], ...sentences.slice(2)], sentLen0_1)
    }
    const sentences = splitSent(text)
    return loop(sentences, stringLength(sentences[0]))
}

// 分割句子，英文版简单版
function splitSent(text) {
    return text.split(".").filter(s => s !== '').map(s => s.trim() + ".")
}

// 计算字符串长度
function stringLength(s) {
    return [...s].length
}

function generateUUID() {
    const charList = [
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']

    function loop(num) {
        const m = num % 62
        const d = Math.floor(num / 62)
        if (d === 0) {
            return charList[m]
        }
        else {
            return loop(d) + charList[m]
        }
    }

    return loop(currentMs() * 10000 + ramdomRange(1000, 9999))
}

function uuid() {
    return uuidv4().replaceAll("-", '')
}

const ramdomRange = (min, max) => (Math.random() * (max - min + 1) | 0) + min

async function httpGet(url) {
    return await axios.get(url)
}

async function httpPost(url, params) {
    return await axios({
        method: 'post',
        url: url,
        data: params
    })
}



function decodeBase64Image(dataString) {
    var matches = dataString.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/),
        response = {};

    if (matches.length !== 3) {
        return new Error('Invalid input string');
    }

    response.type = matches[1];
    response.data = new Buffer(matches[2], 'base64');

    return response;
}


function base64ToFile(base64Data) {

    // Regular expression for image type:
    // This regular image extracts the "jpeg" from "image/jpeg"
    var imageTypeRegularExpression      = /\/(.*?)$/;      

    // Generate random string
    var crypto                          = require('crypto');
    var seed                            = crypto.randomBytes(20);
    var uniqueSHA1String                = crypto
        .createHash('sha1')
        .update(seed)
        .digest('hex');

    var imageBuffer                      = decodeBase64Image(base64Data);
    var userUploadedFeedMessagesLocation = tempMediaPath;

    var uniqueRandomImageName            = 'image-' + uniqueSHA1String;
    var imageTypeDetected                = imageBuffer
        .type
        .match(imageTypeRegularExpression);

    var userUploadedImagePath            = userUploadedFeedMessagesLocation + 
        uniqueRandomImageName +
        '.' + 
        imageTypeDetected[1];

    fs.writeFileSync(userUploadedImagePath, imageBuffer.data);

    return userUploadedImagePath
}

function base64ToFile2(base64Data, filePath) {
    fs.writeFileSync(filePath, new Buffer.from(base64Data, 'base64'));
    return filePath
}

function arraySub(big, small) {
    return big.filter(item => {
        return !small.includes(item)
    })
}

function uniqueItem(arr) {
    return Array.from(new Set(arr))
}

function makeIncArray(start, end) {
    let rs = []
    for (let i = start; i <= end; i++) {
        rs.push(i)
    }
    return rs
}

function getVal(obj, key) {
    return obj[key]
}

const splitArray = (arr, size)=>{  // size=5，要分割的长度
    const arrNum = Math.ceil(arr.length/size, 10) // Math.ceil()向上取整的方法，用来计算拆分后数组的长度
    let index = 0; // 定义初始索引
    let resIndex = 0; // 用来保存每次拆分的长度
    const result = [];
    while(index< arrNum){
        result[index]= arr.slice(resIndex,size+resIndex)
        resIndex += size
        index++
    }
    return result;
}

// 分割数组，平均分成n组
function splitArray2(arr, n) {
    const len = R.length(arr)
    const size = Math.ceil(len / n)
    return splitArray(arr, size)
}

function first(s) {
  if (s && s.length > 0) {
    return s[0]
  }
  return null
}


module.exports = { clearRequireCache, urlEncode, strToTimestamp, nowDateStr, currentSec, currentMs, timestampToStr, shortCNToTimestamp, extractNum, strSentenceCut, splitSent, stringLength, generateUUID, uuid, ramdomRange, httpGet, httpPost, base64ToFile, base64ToFile2, arraySub, uniqueItem, makeIncArray, getVal, splitArray, splitArray2, sleep, first }
